﻿#include <qextProgressButton.h>
#include <qextProgressButton_p.h>

#include <QPainter>
#include <QEvent>
#include <QResizeEvent>
#include <QTimer>
#include <QDebug>

QEXTProgressButtonPrivate::QEXTProgressButtonPrivate(QEXTProgressButton *q)
    : q_ptr(q)
{
    m_lineWidth = 8;
    m_lineColor = QColor(250, 250, 250);
    m_borderWidth = 0;
    m_borderColor = QColor(14, 153, 160);
    m_borderRadius = 5;
    m_backgroundColor = QColor(34, 163, 169);
    m_value = 0;
    m_status = 0;
}

QEXTProgressButtonPrivate::~QEXTProgressButtonPrivate()
{

}



QEXTProgressButton::QEXTProgressButton(QWidget *parent)
    : QWidget(parent)
    , dd_ptr(new QEXTProgressButtonPrivate(this))
{
    Q_D(QEXTProgressButton);
    d->m_timer = new QTimer(this);
    d->m_timer->setInterval(10);
    connect(d->m_timer, SIGNAL(timeout()), SLOT(progress()));
}

QEXTProgressButton::~QEXTProgressButton()
{

}

void QEXTProgressButton::resizeEvent(QResizeEvent *e)
{
    Q_D(QEXTProgressButton);
    d->m_tempWidth = e->size().width();
    this->update();
}

void QEXTProgressButton::mousePressEvent(QMouseEvent *)
{
    Q_D(QEXTProgressButton);
    if(!d->m_timer->isActive()) {
        d->m_status = 0;
        d->m_value = 0.0;
        d->m_tempWidth = this->width();
        d->m_timer->start();
    }
}

void QEXTProgressButton::paintEvent(QPaintEvent *)
{
    Q_D(QEXTProgressButton);
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

    if (1 == d->m_status) {
        this->drawProgress(&painter);
    } else {
        this->drawBackground(&painter);
    }
}

void QEXTProgressButton::drawBackground(QPainter *painter)
{
    Q_D(QEXTProgressButton);
    painter->save();

    int width = this->width();
    int height = this->height();
    int side = qMin(width, height);

    QPen pen;
    pen.setWidth(d->m_borderWidth);
    pen.setColor(d->m_borderColor);
    painter->setPen(d->m_borderWidth > 0 ? pen : Qt::NoPen);
    painter->setBrush(d->m_backgroundColor);

    QRect rect(((width - d->m_tempWidth) / 2) + d->m_borderWidth, d->m_borderWidth, d->m_tempWidth - (d->m_borderWidth * 2), height - (d->m_borderWidth * 2));
    painter->drawRoundedRect(rect, d->m_borderRadius, d->m_borderRadius);

    QFont font;
    font.setPixelSize(side - 18);
    painter->setFont(font);
    painter->setPen(d->m_lineColor);
    painter->drawText(rect, Qt::AlignCenter, d->m_status == 2 ? "完 成" : "开 始");

    painter->restore();
}

void QEXTProgressButton::drawProgress(QPainter *painter)
{
    Q_D(QEXTProgressButton);
    painter->save();

    int width = this->width();
    int height = this->height();
    int side = qMin(width, height);
    int radius = 99 - d->m_borderWidth;

    QPen pen;
    pen.setWidth(d->m_borderWidth);
    pen.setColor(d->m_borderColor);
    painter->setPen(d->m_borderWidth > 0 ? pen : Qt::NoPen);
    painter->setBrush(d->m_backgroundColor);

    QRect rectCircle(-radius, -radius, radius * 2, radius * 2);
    painter->translate(width / 2, height / 2);
    painter->scale(side / 200.0, side / 200.0);
    painter->drawEllipse(rectCircle);

    pen.setWidth(d->m_lineWidth);
    pen.setColor(d->m_lineColor);
    painter->setPen(pen);

    int offset = radius - d->m_lineWidth - 5;
    QRectF rectArc(-offset, -offset, offset * 2, offset * 2);
    int startAngle = offset * 16;
    int spanAngle = -d->m_value * 16;
    painter->drawArc(rectArc, startAngle, spanAngle);

    QFont font;
    font.setPixelSize(offset - 15);
    painter->setFont(font);
    QString strValue = QString("%1%").arg((int)d->m_value  * 100 / 360);
    painter->drawText(rectCircle, Qt::AlignCenter, strValue);

    painter->restore();
}

void QEXTProgressButton::progress()
{
    Q_D(QEXTProgressButton);
    if (0 == d->m_status) {
        d->m_tempWidth -= 5;
        if (d->m_tempWidth < this->height() / 2) {
            d->m_tempWidth = this->height() / 2;
            d->m_status = 1;
        }
    } else if (1 == d->m_status) {
        d->m_value += 1.0;
        if (d->m_value >= 360) {
            d->m_value = 360.0;
            d->m_status = 2;
        }
    } else if (2 == d->m_status) {
        d->m_tempWidth += 5;
        if (d->m_tempWidth > this->width()) {
            d->m_tempWidth = this->width();
            d->m_timer->stop();
        }
    }

    this->update();
}

int QEXTProgressButton::lineWidth() const
{
    Q_D(const QEXTProgressButton);
    return d->m_lineWidth;
}

QColor QEXTProgressButton::lineColor() const
{
    Q_D(const QEXTProgressButton);
    return d->m_lineColor;
}

int QEXTProgressButton::borderWidth() const
{
    Q_D(const QEXTProgressButton);
    return d->m_borderWidth;
}

QColor QEXTProgressButton::borderColor() const
{
    Q_D(const QEXTProgressButton);
    return d->m_borderColor;
}

int QEXTProgressButton::borderRadius() const
{
    Q_D(const QEXTProgressButton);
    return d->m_borderRadius;
}

QColor QEXTProgressButton::backgroundColor() const
{
    Q_D(const QEXTProgressButton);
    return d->m_backgroundColor;
}

QSize QEXTProgressButton::sizeHint() const
{
    return QSize(200, 80);
}

QSize QEXTProgressButton::minimumSizeHint() const
{
    return QSize(30, 15);
}

void QEXTProgressButton::setLineWidth(int width)
{
    Q_D(QEXTProgressButton);
    if (d->m_lineWidth != width) {
        d->m_lineWidth = width;
        this->update();
    }
}

void QEXTProgressButton::setLineColor(const QColor &color)
{
    Q_D(QEXTProgressButton);
    if (d->m_lineColor != color) {
        d->m_lineColor = color;
        this->update();
    }
}

void QEXTProgressButton::setBorderWidth(int width)
{
    Q_D(QEXTProgressButton);
    if (d->m_borderWidth != width) {
        d->m_borderWidth = width;
        this->update();
    }
}

void QEXTProgressButton::setBorderColor(const QColor &color)
{
    Q_D(QEXTProgressButton);
    if (d->m_borderColor != color) {
        d->m_borderColor = color;
        this->update();
    }
}

void QEXTProgressButton::setBorderRadius(int radius)
{
    Q_D(QEXTProgressButton);
    if (d->m_borderRadius != radius) {
        d->m_borderRadius = radius;
        this->update();
    }
}

void QEXTProgressButton::setBackgroundColor(const QColor &color)
{
    Q_D(QEXTProgressButton);
    if (d->m_backgroundColor != color) {
        d->m_backgroundColor = color;
        this->update();
    }
}
